﻿#include "UdpSocket.h"

#include <QByteArray>
#include <QTimer>
#include <QDateTime>

#include "MainWindow.h"

UdpSocket::UdpSocket(QObject *parent) :
    QObject(parent),
    m_sendMsgLenCnt(0),
    m_revMsgLenCnt(0),
    m_socket(new QUdpSocket(this))
{
    connect(m_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
}

void UdpSocket::cleanup()
{
    stopListen();
    delete m_socket;
    m_socket = nullptr;
}

bool UdpSocket::listen(const QHostAddress &ip, int port)
{
    if (m_socket->isValid()) {
        stopListen();
    }

    if (m_socket->bind(ip, port)) {
        emit sigSystemLog("TCP开始监听" + MainWindow::getIpAndPortStr(ip, port) + "，等待客户端接入");
        return true;
    } else {
        emit sigSystemLog("TCP服务器监听失败！");
        return false;
    }

    return m_socket->isValid();
}

bool UdpSocket::stopListen()
{
    if (m_socket->isValid()) {
        m_socket->close();
        m_socket->abort();
    }
    m_clientObjList.clear();
    emit sigClientUpdate();

    return !m_socket->isOpen();
}

void UdpSocket::deleteClient(const QString &clientStr)
{
    if (m_clientObjList.contains(clientStr)) {
        m_clientObjList.removeAll(clientStr);
    }
    emit sigClientUpdate();
}

void UdpSocket::sendMsgToClient(const QString &ip, int port, const QByteArray &msg)
{
    m_socket->writeDatagram(msg.data(), msg.length(), QHostAddress(ip), port);

    m_sendMsgLenCnt += msg.size();
    emit sigCNTUpdate(m_sendMsgLenCnt, m_revMsgLenCnt);
}

void UdpSocket::sendMsgToClient(const QString &clientStr, const QByteArray &msg)
{
    if (clientStr.contains(QHostAddress(QHostAddress::Broadcast).toString()) || (m_clientObjList.contains(clientStr) && clientStr.contains(':'))) {
        sendMsgToClient(clientStr.split(':').first(), clientStr.split(':').last().toInt(), msg);
    }
}

void UdpSocket::sendData(const QByteArray &buffer, const QString &ip, int port)
{
    m_socket->writeDatagram(buffer.data(), buffer.size(), QHostAddress(ip), port);
}

void UdpSocket::onReadyRead()
{
    QByteArray datagram;
    while (m_socket->hasPendingDatagrams()) {
        QHostAddress address;
        quint16 port;

        datagram.resize(m_socket->pendingDatagramSize());           //根据可读数据来设置空间大小
        m_socket->readDatagram(datagram.data(), datagram.size(),&address,&port);   //读取数据

        address = QHostAddress(address.toIPv4Address());
        m_revMsgLenCnt += datagram.size();
        emit sigReadMsg(MainWindow::getIpAndPortStr(address, port), datagram);
        emit sigCNTUpdate(m_sendMsgLenCnt, m_revMsgLenCnt);

        if (!m_clientObjList.contains(MainWindow::getIpAndPortStr(address, port))) {
            m_clientObjList.append(MainWindow::getIpAndPortStr(address, port));
            emit sigClientUpdate();
        }
    }
}
